#include<iostream>
using namespace std;

class Point2d
{
	public:
		Point2d(float = 0.0, float = 0.0);
		virtual ~Point2d();
		virtual float z();
		void number();
	protected:
		float _x, _y;
};

Point2d::Point2d(float x, float y) : _x(x), _y(y)
{}

Point2d::~Point2d()
{}

float Point2d::z()
{
	return 0.0;
}

void Point2d::number()
{}
/////////////////////////////////////////////////
class Point3d : public Point2d
{
	public:
		Point3d(float = 0.0, float = 0.0, float = 0.0);
		~Point3d();
		float z();
	protected:
		float _z;
};

Point3d::Point3d(float x, float y, float z) : Point2d(x,y), _z(z)
{}

Point3d::~Point3d()
{}

float Point3d::z()
{
	return _z;
}

int main(int argc, char *argv[])
{
	void (Point2d::*numberPtr)();
	numberPtr = &Point2d::number;
	//member function point to non-virtual function is its real address
	printf("numberPtr(nonvirtual): %p\n", numberPtr);
	
	float (Point2d::*zptr)();
	zptr = &Point2d::z;
	//member function point to virtual function is its offset to vtable
	printf("zptr(virtual): %p\n", zptr);	

	Point3d p3d(1,2,3);
	//invoke by member function point can also show polymorphism
	cout << (p3d.*zptr)() << endl;
	return 0;
}
